# -*- coding: utf-8 -*-
# @author: edgardeng
# @date:   2021-05-08
# @file:   在sanic中使用websocket

from sanic import Sanic
from sanic.response import text
import aioredis

app = Sanic("My Hello, world app")


# websocket_cfg = dict(
#     WEBSOCKET_MAX_SIZE=2 ** 20,
#     WEBSOCKET_MAX_QUEUE=32,
#     WEBSOCKET_READ_LIMIT=2 ** 16,
#     WEBSOCKET_WRITE_LIMIT=2 ** 16,
#     WEBSOCKET_PING_INTERVAL=20,
#     WEBSOCKET_PING_TIMEOUT=20
# )
# app.config.update(websocket_cfg)

@app.listener("before_server_start")
async def setup_db(server_app, loop):
    _t = ('127.0.0.1', '6379')
    server_app.ctx.aio_cli = await aioredis.create_redis_pool(_t, encoding="utf-8",
                                                              db=6,
                                                              loop=loop)


@app.get("/")
async def hello_world(request):
    return text("Hello, world.")


@app.websocket("/feed")
async def feed(request, ws):
    data = await ws.recv()
    replay = '[Sanic] ' + data
    await ws.send(replay)  # 短链接只发一次


@app.websocket("/feed2")  # Typically, a websocket handler will want to hold open a loop.
async def feed2(request, ws):
    while True:
        data = await ws.recv()
        if data == 'exit':
            print("Received: " + data)
            break
        replay = '[Sanic] ' + data
        await ws.send(replay)
    # 长连接


@app.websocket("/channel_status")
async def channel_status(request, ws):
    channel = await ws.recv()
    redis = request.app.ctx.aio_cli
    redis_sub, = await redis.subscribe(channel)
    print(channel)
    while True:
        print('wait redis channel_status...')
        try:
            status = await redis_sub.get()  # 第一条默认 [,channel,cnt]
            print(status)
        except Exception as e:
            print(e)

        replay = '[Sanic] Channel:%s, Status: %s' % (channel, status)
        await ws.send(replay)
        channel = await ws.recv()


@app.websocket("/channel_on")
async def channel_status(request, ws):
    redis = request.app.ctx.aio_cli
    try:
        while True:
            data = await ws.recv()
            print(data)
            channel_status = data.split(':')
            await redis.publish(channel_status[0], channel_status[1])
            replay = '[Sanic] Channel:%s, Status: %s OK' % (channel_status[0], channel_status[1])
            await ws.send(replay)
    except Exception as e:
        print(e)



if __name__ == '__main__':
    app.run()
